'use strict';
import manifest from '@/manifest.json';

export default class Update {
    constructor(option = {}) {
        this.isInit = option.isInit || false;
        this.updateInfoKey = option.updateInfoKey || '__update_info__';
        this.checkUpdateUrl = option.checkUpdateUrl ||
            'https://app.fjxiaoni.com/app-server/app/upgrade';
        this.device = null;
        this.updateInfo = null;
        this.tempFilePath = null;
        this.downloading = false;
        this.downloadTask = null;
        this.downloadProgress = 0;
        this.downloadedSize = 0;
        this.packageFileSize = 0;

        this.installed = false;
        this.installing = false;

        this.isInit && this.init();
    }

    /**
     * @description 检测更新
     */
    checkAppUpdate() {
        this.getDeviceInfo(deviceInfo => {
            this.device = deviceInfo;
            uni.request({
                url: this.checkUpdateUrl,
                data: deviceInfo,
                method: 'POST',
                success: (res) => {
                    if (res.data.data.version) {
                        let updateInfo = res.data.data.version;
                        let installType = updateInfo.installType;
                        let versionCompareResult = this.versionCompare(updateInfo.versionOut,
                            this.device.version);
                        if (versionCompareResult == 1) {
                            // apk
                            if (installType === 'apk' && deviceInfo.platform == 'android') {
                                uni.setStorageSync(this.updateInfoKey, updateInfo);
                                if (updateInfo.silenceUpdate == 1) {
                                    this.silenceUpdate(updateInfo);
                                    return;
                                };
                                if (updateInfo.forcedUpdate == 1) {
                                    uni.navigateTo({
                                        url: '/components/upgrade-popup/upgrade-popup',
                                        fail: (err) => {
                                            console.error('更新弹框跳转失败', err)
                                        }
                                    });
                                    return;
                                };
                                uni.navigateTo({
                                    url: '/components/upgrade-popup/upgrade-popup',
                                    fail: (err) => {
                                        console.error('更新弹框跳转失败', err)
                                    }
                                });
                            }
                            // wgt
                            if (installType === 'wgt') {
                                uni.setStorageSync(this.updateInfoKey, updateInfo);
                                if (updateInfo.silenceUpdate == 1) {
                                    this.silenceUpdate(updateInfo);
                                    return;
                                };
                                if (updateInfo.forcedUpdate == 1) {
                                    uni.navigateTo({
                                        url: '/components/upgrade-popup/upgrade-popup',
                                        fail: (err) => {
                                            console.error('更新弹框跳转失败', err)
                                        }
                                    });
                                    return;
                                };
                                uni.navigateTo({
                                    url: '/components/upgrade-popup/upgrade-popup',
                                    fail: (err) => {
                                        console.error('更新弹框跳转失败', err)
                                    }
                                });
                            }
                        }
                    } else {
                        console.log(res);
                    }
                },
                fail: (err) => {
                    console.log(err);
                }
            });
        });
    }

    /**
     * @description 静默更新
     * @param {Object} updateInfo 更新信息
     */
    silenceUpdate(updateInfo) {
        let requiredKey = ['version', 'downloadUrl', 'installType'];
        for (let key in updateInfo) {
            if (requiredKey.indexOf(key) !== -1 && !updateInfo[key]) {
                console.error(`参数 ${key} 必填，请检查后重试`);
                uni.navigateBack();
                return;
            }
        }
        this.updateInfo = updateInfo;
        const versionCompareResult = this.versionCompare(updateInfo.versionOut, this.device.version);
        if (versionCompareResult == 1) {
            uni.downloadFile({
                url: this.updateInfo.downloadUrl,
                success: res => {
                    if (res.statusCode == 200) {
                        this.tempFilePath = res.tempFilePath;
                        plus.runtime.install(this.tempFilePath, {
                                force: true
                            },
                            success => {
                                if (this.tempFilePath) this.tempFilePath = null;
                                uni.removeStorageSync(this.updateInfoKey);
                            },
                            error => {
                                console.log(error);
                            }
                        );
                    }
                },
                fail: err => {
                    console.log(err);
                }
            });
        }
    };

    /**
     * @description 手动更新
     * @param {Object} updateInfo 更新信息
     */
    manualUpdate() {
        if (this.downloading) {
            uni.showToast({
                mask: true,
                icon: 'none',
                title: '下载中...',
                duration: 1500
            })
            return;
        }

        let requiredKey = ['version', 'downloadUrl', 'installType'];
        for (let key in this.updateInfo) {
            if (requiredKey.indexOf(key) !== -1 && !this.updateInfo[key]) {
                console.error(`参数 ${key} 必填，请检查后重试`);
                uni.navigateBack();
                return;
            }
        }
        const versionCompareResult = this.versionCompare(this.updateInfo.versionOut, this.device.version);
        if (versionCompareResult == 1) {
            this.downloading = true;
            this.downloadTask = uni.downloadFile({
                url: this.updateInfo.downloadUrl,
                success: res => {
                    if (res.statusCode == 200) {
                        this.installing = true;
                        this.tempFilePath = res.tempFilePath;
                        plus.runtime.install(this.tempFilePath, {
                                force: true
                            },
                            success => {
                                if (this.tempFilePath) this.tempFilePath = null;
                                this.installed = true;
                                this.installing = false;
                                uni.removeStorageSync(this.updateInfoKey);
                                if (this.updateInfo.installType == 'wgt') {
                                    uni.showToast({
                                        title: '应用更新成功,应用即将重启',
                                        mask: true,
                                        icon: 'none',
                                        duration: 2000,
                                    })
                                    setTimeout(() => {
                                        this.downloading = false;
                                        this.downloadProgress = 0;
                                        plus.runtime.restart();
                                    }, 2000)
                                }
                            },
                            error => {
                                console.log(error);
                            }
                        );
                    } else {
                        console.log(err);
                    }
                },
                complete: () => {
                    this.downloadedSize = 0;
                    this.packageFileSize = 0;
                    this.downloadTask = null;
                },
                fail: err => {
                    console.log(err);
                }
            });

            this.downloadTask.onProgressUpdate(progress => {
                this.downloadProgress = progress.progress;
                this.downloadedSize = (progress.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);
                this.packageFileSize = (progress.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);
            })

        } else {
            uni.showToast({
                mask: true,
                icon: 'none',
                duration: 3000,
                title: '当前已经是最新版本'
            })
        }
    }

    /**
     * @description 初始化
     */
    init() {
        this.getDeviceInfo(deviceInfo => {
            this.device = deviceInfo;
            this.updateInfo = uni.getStorageSync(this.updateInfoKey);
            if (!localPackageInfo) {
                console.error('安装包信息为空，请检查后重试');
                uni.navigateBack();
                return;
            }

            let requiredKey = ['version', 'downloadUrl', 'installType'];
            for (let key in localPackageInfo) {
                if (requiredKey.indexOf(key) !== -1 && !localPackageInfo[key]) {
                    console.error(`参数 ${key} 必填，请检查后重试`);
                    uni.navigateBack();
                    return;
                }
            }
        });
    }

    /**
     * @description 关闭更新
     */
    async closeUpdate() {
        if (this.downloading) {
            if (this.isForcedUpdate) {
                return uni.showToast({
                    title: '下载中，请稍后……',
                    icon: 'none',
                    duration: 500
                });
            }
            uni.showModal({
                title: '是否取消下载?',
                cancelText: '否',
                confirmText: '是',
                success: res => {
                    if (res.confirm) {
                        this.downloadTask && this.downloadTask.abort();
                        uni.navigateBack();
                    }
                }
            });
            return;
        }
        uni.navigateBack()
    }

    /**
     * @description 对比版本号，如需要，请自行修改判断规则
     * @description 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
     * @param {String} v1 版本号
     * @param {String} v2 版本号
     * * v1 > v2 return 1
     * v1 < v2 return -1
     * v1 == v2 return 0
     */
    versionCompare(v1 = '0', v2 = '0') {
        v1 = String(v1).split('.');
        v2 = String(v2).split('.');
        const minVersionLens = Math.min(v1.length, v2.length);

        let result = 0;
        for (let i = 0; i < minVersionLens; i++) {
            const curV1 = Number(v1[i]);
            const curV2 = Number(v2[i]);

            if (curV1 > curV2) {
                result = 1;
                break;
            } else if (curV1 < curV2) {
                result = -1;
                break;
            }
        }

        if (result === 0 && v1.length !== v2.length) {
            const v1BiggerThenv2 = v1.length > v2.length;
            const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
            for (let i = minVersionLens; i < maxLensVersion.length; i++) {
                const curVersion = Number(maxLensVersion[i]);
                if (curVersion > 0) {
                    v1BiggerThenv2 ? (result = 1) : (result = -1);
                    break;
                }
            }
        }

        return result;
    }

    /**
     * @description 获取设备信息
     * @param {Function} callback 回调函数
     */
    getDeviceInfo(callback = () => {}) {
        let device = {};
        // 开发环境和生产环境判断
        let env = null;
        // #ifdef MP-WEIXIN
        env = uni.getAccountInfoSync().miniProgram.envVersion; // 获取微信运行环境
        // #endif
        // #ifndef MP-WEIXIN
        env = process.env.NODE_ENV; // 获取除了微信以外的运行环境
        // #endif
        uni.getSystemInfo({
            success: (systemInfo) => {
                Object.assign(device, {
                    env
                });
                Object.assign(device, systemInfo);
                plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
                    Object.assign(device, widgetInfo);
                    plus.device.getInfo({
                        success: (info) => {
                            Object.assign(device, info);
                            device.appid = manifest.appid;
                            callback(device)
                        }
                    })
                });
            }
        });
    }

}
